home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / advancec.arc / GRFUSER.C < prev    next >
Text File  |  1992-01-24  |  31KB  |  1,200 lines

  1. /*
  2.  *    user functions for IBM PC
  3.  * 
  4.  *     if using the Microsoft, Lattice, or Ecosoft compiler
  5.  *    which have a dos.h include file and use the int86() function
  6.  *    call in place of sysint(), uncomment the #define OTHER below
  7.  *
  8.  *    If using the Microsoft compiler, also uncomment the #define MICROSOFT
  9.  * and compiler this module enabling the far keyword (/Ze for MSC, /Me for CL)
  10.  * The peek() function at the end of this module requires a pointer to
  11.  * a far object.
  12.  *
  13.  *    WARNING: It is the programmers responsibility to provide
  14.  *    proper scaling of x,y coordinates for the type of display used.
  15.  *    The original program files assume a 1024 x 1024 screen. The
  16.  *    should either provide routines to scale the incoming coordinates
  17.  *    to the type of graphics screen used or alter the functions in 
  18.  *    the other directories to conform to the type of screen.
  19.  *    
  20.  */
  21.  
  22. /* #define OTHER 1 */
  23. /* #define MICROSOFT 1 */
  24.  
  25. #include <stdio.h>
  26. #include "defs.h"
  27.  
  28. #ifdef OTHER
  29. #include <dos.h>
  30. #endif
  31.  
  32. static int CURx = 0, CURy = 0;    /* Current cursor location */
  33.  
  34. /* Structure for the c86 regs to be passed to sysint call */
  35.  
  36. #ifndef OTHER
  37.  
  38. typedef struct regs {
  39.             int ax, bx, cx, dx, si, di, ds, es;
  40.             } REG_ST;
  41.  
  42. #else
  43. #ifndef MICROSOFT
  44.  
  45. typedef struct XREGS REG_ST;
  46.  
  47. #else
  48.  
  49. typedef struct WORDREGS REG_ST;
  50.  
  51. #endif
  52.  
  53. #define sysint(a,b,c) int86(a,b,c)
  54.  
  55. #endif
  56.  
  57. static REG_ST reg1, reg2;
  58. static char mode, page, color, colorb;
  59. static int OVALF = 0;
  60.  
  61. extern int rx1, rx2, ry1, ry2;
  62. extern rect_t screen, *cur_win, *cur_port;
  63.  
  64. #define abs(x)    ( ( x ) < 0 ? ( -x ) : ( x ) )
  65.  
  66. #define UP    1
  67. #define DN    3
  68. #define RT    4
  69. #define LT   12
  70. #define UPLT 13
  71. #define UPRT  5
  72. #define DNRT  7
  73. #define DNLT 15
  74.  
  75. double do_d();
  76. char get_move();
  77.  
  78. /*+1***************************************************************************/
  79. /*                                          */
  80. /*    initialize  -    Initializes the screen                      */
  81. /*                                          */
  82. /*    description -    Sets the color to white, sets the screen to 320 x 200 */
  83. /*            graphics, draws a square around the screen, and sets  */
  84. /*            the global screen window                  */
  85. /*                                          */
  86. /*    parameters  -    initialize()                          */
  87. /*                                          */
  88. /*    returns     -    NOTHING                           */
  89. /*                                          */
  90. /*    Programmer  -    Jeff Wrench                          */
  91. /*                                          */
  92. /*-1***************************************************************************/
  93.  
  94. initialize()
  95. {
  96.     CURx = CURy = 0;
  97.     set_rect(&screen,0,0,319,199);    /* set global screen rectangle */
  98.     cur_win = cur_port = &screen;
  99.     reg1.ax = 0x0f00;            /* get finish values for terminate */
  100.     sysint(0x10,®1,®2);
  101.     page = reg2.bx >> 8;        /* moniter page to reset to */
  102.     mode = reg2.ax;            /* screen mode to reset to */
  103.     reg1.ax = 4;
  104.     sysint(0x10, ®1, ®2);     /* set to 320 x 200 color graph mode */
  105.     set_color(WHITE);
  106.     line_to(319, 0);            /* do screen rectangle */
  107.     line_to(319, 199);
  108.     line_to(0,     199);
  109.     line_to(0,     0);
  110. }
  111.  
  112. /*+1***************************************************************************/
  113. /*                                          */
  114. /*    set_color   -    set the draw color                      */
  115. /*                                          */
  116. /*    description -    sets the glogal drawing color - CAUTION: Most of the  */
  117. /*            eight colors use 2 pixels per color. this is in color */
  118. /*            graphics mode, the IBM only gives you 4 colors, so    */
  119. /*            I had to combine them in pairs to get all eight colors*/
  120. /*                                          */
  121. /*    parameters  -    get_color(col)                          */
  122. /*            int col;    The color to be set to              */
  123. /*                                          */
  124. /*    Returns     -    Nothing                           */
  125. /*                                          */
  126. /*    Programmer  -    Jeff Wrench                          */
  127. /*                                          */
  128. /*-1***************************************************************************/
  129.  
  130. set_color(col)
  131. int col;
  132. {
  133.     switch(col)
  134.     {
  135.     case BLACK  :    /* set display's equivalent color code */
  136.             color = 0;
  137.             break;
  138.     case WHITE  :
  139.             color = 15;
  140.             break;
  141.     case RED    :
  142.             color = 2;
  143.             break;
  144.     case GREEN  :
  145.             color = 5;
  146.             break;
  147.     case BLUE   :
  148.             color = 8;
  149.             break;
  150.     case MAGENTA :
  151.             color = 10;
  152.             break;
  153.     case CYAN   :
  154.             color = 4;
  155.             break;
  156.     case YELLOW :
  157.             color = 3;
  158.             break;
  159.     }
  160. }
  161.  
  162. /*+1***************************************************************************/
  163. /*                                          */
  164. /*    terminate   -    Reset the system                      */
  165. /*                                          */
  166. /*    description -    reset the system to the way it was before the          */
  167. /*            initialize call                       */
  168. /*                                          */
  169. /*    parameters  -    terminate()                          */
  170. /*                                          */
  171. /*    returns     -    Nothing                           */
  172. /*                                          */
  173. /*    Programmer  -    Jeff Wrench                          */
  174. /*                                          */
  175. /*-1***************************************************************************/
  176.  
  177. terminate()
  178. {
  179.     reg1.ax = mode;            /* reset the mode */
  180.     sysint(0x10, ®1, ®2);
  181.     if ( page )             /* if was on page other than 1 reset it */
  182.     {
  183.     reg1.ax = 0x500 | page;
  184.     sysint(0x10, ®1, ®2);
  185.     }
  186. }
  187.  
  188. /*+1***************************************************************************/
  189. /*                                          */
  190. /*    line        -    Draw a line                          */
  191. /*                                          */
  192. /*    description -    Draws a line from the current location to the          */
  193. /*            location referenced by CURx + x, CURy + y.  It also   */
  194. /*            updated ( CURx, CURy ) to point to the end of the     */
  195. /*            line.                              */
  196. /*                                          */
  197. /*    parameters  -    line(x,y)                          */
  198. /*            int x;        The Dx to move                  */
  199. /*            int y;        The Dy to move                  */
  200. /*                                          */
  201. /*    returns     -    Nothing                           */
  202. /*                                          */
  203. /*    Programmer  -    Jeff Wrench                          */
  204. /*                                          */
  205. /*-1***************************************************************************/
  206.  
  207. line(x1,y1)
  208. int    x1,y1;
  209. {
  210. int x2, y2;         /* The end point*/
  211. int x, y;
  212. int adx, ady;         /* The Distance to move */
  213. int xa, ya;         /* The direction to move */
  214. int d;             /* The distance already moved */
  215. int incr1, incr2;     /* The distance moved each time */
  216. int savx, savy;
  217.  
  218.  
  219.     if ( clipper ( CURx, CURy, x1 + CURx, y1 + CURy, cur_win ) )
  220.     {
  221.     savx = rx2;
  222.     savy = ry2;
  223.  
  224.     map ( &rx1, &ry1 );      /* map to screen coordinates */
  225.     map ( &rx2, &ry2 );
  226.  
  227.     colorb = ( color >> 2 ) & 3;
  228.  
  229.     x = rx2 - rx1;
  230.     y = ry2 - ry1;
  231.  
  232.     if ( x < 0 )          /* Set up to move backwards on the X-axis */
  233.     {
  234.         xa = -1;
  235.         adx = -x;
  236.     }
  237.     else            /* Set up to move forwards on the X-axis */
  238.     {
  239.         xa =  1;
  240.         adx =  x;
  241.     }
  242.  
  243.     if ( y < 0 )          /* Set up to move backwards on the Y-axis */
  244.     {
  245.         ya = -1;
  246.         ady = -y;
  247.     }
  248.     else            /* Set up to move forwards on the Y-axis */
  249.     {
  250.         ya =  1;
  251.         ady =  y;
  252.     }
  253.  
  254.     if (adx > ady)        /* Are we moving more over than up */
  255.     {
  256.         incr1 = ady << 1;
  257.         d = incr1 - adx;
  258.         incr2 = incr1 - ( adx << 1 );
  259.         while ( rx1 != rx2 )
  260.         {
  261.         rx1 += xa;
  262.         if (d < 0)
  263.             d += incr1;
  264.         else
  265.         {
  266.             ry1 += ya;
  267.             d += incr2;
  268.         }
  269.         CURx = rx1;
  270.         CURy = ry1;
  271.         do_pix();
  272.         }
  273.     }
  274.     else                /* Are we going more over than up */
  275.     {
  276.         incr1 = adx << 1;
  277.         d = incr1 - ady;
  278.         incr2 = incr1 - ( ady << 1 );
  279.         while ( ry1 != ry2 )
  280.         {
  281.         ry1 += ya;
  282.         if (d < 0)
  283.             d += incr1;
  284.         else
  285.         {
  286.             rx1 += xa;
  287.             d += incr2;
  288.         }
  289.         CURx = rx1;
  290.         CURy = ry1;
  291.         do_pix();
  292.         }
  293.     }
  294.  
  295.     CURx = savx;
  296.     CURy = savy;
  297.     }
  298. }
  299.  
  300. /*+1***************************************************************************/
  301. /*                                          */
  302. /*    line_to     -    Draw a line                          */
  303. /*                                          */
  304. /*    description -    Draws a line from the current location to the          */
  305. /*            location referenced by ( x, y ).  It also updated     */
  306. /*            ( CURx, CURy ) to point to the end of the          */
  307. /*            line.                              */
  308. /*                                          */
  309. /*    parameters  -    line(x,y)                          */
  310. /*            int x;        The Absolute position to move to      */
  311. /*            int y;        The Absolute position to move to      */
  312. /*                                          */
  313. /*    returns     -    Nothing                           */
  314. /*                                          */
  315. /*    Programmer  -    Jeff Wrench                          */
  316. /*                                          */
  317. /*-1***************************************************************************/
  318.  
  319. line_to(x,y)
  320. int x,y;
  321. {
  322.  
  323.     line ( x - CURx, y - CURy );   /* Just convert to a relative move */
  324. }
  325.  
  326. /*+1***************************************************************************/
  327. /*                                          */
  328. /*    text_bbox   -    sets bounding box for text                  */
  329. /*                                          */
  330. /*    description -    sets the bounding box for a text string using the     */
  331. /*            justifation given.                      */
  332. /*                                          */
  333. /*    parameters  -    text_bbox(string, jh, jv)                  */
  334. /*            char *string;        string to bound           */
  335. /*            char jh;        horizontal justification      */
  336. /*            char jv;        vertical justification          */
  337. /*                                          */
  338. /*    returns     -    a pointer ot a bounding box for the text string       */
  339. /*                                          */
  340. /*    Porgrammer  -    Jeff Wrench                          */
  341. /*                                          */
  342. /*-1***************************************************************************/
  343.  
  344. rect_t *text_bbox(string, jh, jv)
  345. char *string, jh, jv;
  346. {
  347. int len;
  348. rect_t *retval;
  349.  
  350.     len = strlen(string) * 8;        /* length in pixels of string */
  351.  
  352.     retval = inst_rect(0, 0, len, 8);    /* get rectangle for LEFT BOTTOM just */
  353.  
  354.     switch ( (int) jh )     /* Justify it horizontially */
  355.     {
  356.     case MIDDLE:
  357.             offset_rect ( retval, ( - len ) / 2, 0 );
  358.             break;
  359.     case RIGHT:
  360.             offset_rect ( retval, - len, 0 );
  361.             break;
  362.     }
  363.  
  364.     switch ( (int) jv )     /* justify it vertically */
  365.     {
  366.     case TOP:
  367.             offset_rect ( retval, 0, -8 );
  368.             break;
  369.     case CENTER:
  370.             offset_rect ( retval, 0, -4 );
  371.             break;
  372.     }
  373.  
  374.     return ( retval );    /* return the bounding box */
  375. }
  376.  
  377. /*+1***************************************************************************/
  378. /*                                          */
  379. /*    draw_text   -    draw a string on the screen                  */
  380. /*                                          */
  381. /*    description -    Draws String at ( X, Y ) with justification          */
  382. /*                                          */
  383. /*    parameters  -    draw_text(string, x, y, bbox);                  */
  384. /*            char *string;        string to print           */
  385. /*            int x, y;        where to print the string     */
  386. /*            rect_t *bbox;        justification from text_bbox  */
  387. /*                                          */
  388. /*    returns     -    nothing                           */
  389. /*                                          */
  390. /*    Programmer  -    Jeff Wrench                          */
  391. /*                                          */
  392. /*-1***************************************************************************/
  393.  
  394. draw_text(string, x, y, bbox)
  395. char *string;
  396. int x, y;
  397. rect_t *bbox;
  398. {
  399. int chrx, chry;
  400. char *str;
  401.  
  402.     x += bbox->left;          /* get upper left of first character */
  403.     y += bbox->top;
  404.  
  405.     /* map viewable bbox */
  406.     map( &x, &y);   /* map to screen */
  407.  
  408.     for ( str = string; *str; str++, x += 8 )    /* print the characters */
  409.     genchr(x, y, *str);
  410. }
  411.  
  412. /*+1***************************************************************************/
  413. /*                                          */
  414. /*    fill_rect   -    Fills a rectangle                      */
  415. /*                                          */
  416. /*    description -    Fills a rectangle after clipping it to the window     */
  417. /*                                          */
  418. /*    parameters  -    fill_rect(rect_pointer)                   */
  419. /*            rect_t *rect_pointer    rectangle to be filled          */
  420. /*                                          */
  421. /*    returns     -    nothing                           */
  422. /*                                          */
  423. /*    Programmer  -    Jeff Wrench                          */
  424. /*                                          */
  425. /*-1***************************************************************************/
  426.  
  427. fill_rect(rect_pointer)
  428. rect_t *rect_pointer;
  429. {
  430. int i, j;
  431. int savx, savy;
  432. rect_t r;
  433.  
  434.     savx = CURx;
  435.     savy = CURy;
  436.  
  437.     if(sect_rect(rect_pointer, cur_win, &r))    /* clip the rectangle */
  438.     {
  439.     for ( i = r.bottom; i <= r.top; i++ )    /* fill one line at a time */
  440.     {
  441.         CURy = i;
  442.         CURx = r.left;
  443.         line_to ( r.right, CURy );
  444.     }
  445.     }
  446.     CURx = savx;
  447.     CURy = savy;
  448. }
  449.  
  450. /*+1***************************************************************************/
  451. /*                                          */
  452. /*    clear_vport -    clears the current view port                  */
  453. /*                                          */
  454. /*    description -    clears the current view_port and redwaws the screen   */
  455. /*            rectangle                          */
  456. /*                                          */
  457. /*    parameters  -    clear_vport(vport)                      */
  458. /*            vport_t *vport;     the view port to be cleared   */
  459. /*                                          */
  460. /*    returns     -    nothing                           */
  461. /*                                          */
  462. /*    programmer  -    Jeff Wrench                          */
  463. /*                                          */
  464. /*-1***************************************************************************/
  465.  
  466. clear_vport(vport)
  467. vport_t *vport;
  468. {
  469. int i, j;
  470. char tmpcolor;
  471.  
  472.     tmpcolor = color;
  473.  
  474.     i = CURx;
  475.     j = CURy;
  476.  
  477.     set_color(vport->bkgnd);
  478.  
  479.     fill_rect ( vport->bitmap );  /* fill the view port wigh background */
  480.  
  481.     set_color(vport->brder);
  482.  
  483.     CURx = vport->bitmap->left;
  484.     CURy = vport->bitmap->top;
  485.  
  486.     /* draw the boarder */
  487.  
  488.     line_to(vport->bitmap->right, vport->bitmap->top);
  489.     line_to(vport->bitmap->right, vport->bitmap->bottom);
  490.     line_to(vport->bitmap->left, vport->bitmap->bottom);
  491.     line_to(vport->bitmap->left, vport->bitmap->top);
  492.  
  493.     CURx = i;
  494.     CURy = j;
  495.  
  496.     color = tmpcolor;
  497. }
  498.  
  499. /*+1***************************************************************************/
  500. /*                                          */
  501. /*    fill_oval   -    fills an oval                          */
  502. /*                                          */
  503. /*    description -    Fills an oval bounded by rect_pointer, It calls       */
  504. /*            frame_oval() to save code                  */
  505. /*                                          */
  506. /*    parameters  -    fill_oval ( rect_pointer )                  */
  507. /*            rect_t *rect_pointer;    bounting box of oval to fill  */
  508. /*                                          */
  509. /*    returns     -    nothing                           */
  510. /*                                          */
  511. /*    Programmer  -    Jeff Wrench                          */
  512. /*                                          */
  513. /*-1***************************************************************************/
  514.  
  515. fill_oval(rect_pointer)
  516. rect_t *rect_pointer;
  517. {
  518.     OVALF = 1;        /* say we're filling */
  519.  
  520.     frame_oval(rect_pointer);    /* do the fill */
  521.  
  522.     OVALF = 0;        /* go back to default frame */
  523. }
  524.  
  525.  
  526. /*+1***************************************************************************/
  527. /*                                          */
  528. /*    frame_oval   -     frames an oval                       */
  529. /*                                          */
  530. /*    description -    Frames an oval bounded by rect_pointer.           */
  531. /*                                          */
  532. /*    parameters  -    fill_oval ( rect_pointer )                  */
  533. /*            rect_t *rect_pointer;    bounting box of oval to fill  */
  534. /*                                          */
  535. /*    returns     -    nothing                           */
  536. /*                                          */
  537. /*    Programmer  -    Jeff Wrench                          */
  538. /*                                          */
  539. /*-1***************************************************************************/
  540.  
  541.  
  542. frame_oval(rect_pointer)
  543. rect_t *rect_pointer;
  544. {
  545. int x, y, alpha, beta, u, v;
  546. long k;
  547. long k1, k2, k3, a, b;
  548. long d;
  549. int *coord1, *coord2, *coord3, d1, d2, d3;
  550. int w;
  551. int count;
  552. int oldx, oldy;
  553. int xoff, yoff;
  554. int left, right, top, bottom;
  555. int xcent, ycent;
  556. rect_t r;
  557.  
  558.     if(sect_rect(rect_pointer, cur_win, &r))    /* clip it down if needed */
  559.     {
  560.     map( &(r.left),  &(r.bottom));    /* map to screen */
  561.     map( &(r.right), &(r.top));
  562.  
  563.     /* xoff is the distance from the left to center of oval */
  564.     xoff = ( ( r.right - r.left ) / 2 ) + r.left;
  565.  
  566.     /* yoff is the distance from the top to center of oval */
  567.     yoff = ( ( r.bottom - r.top ) / 2 ) + r.top;
  568.  
  569.     /*make center relative 0,0 */
  570.     xcent = ycent = 0;
  571.  
  572.     /* move bounding box so the center is relative at 0,0 */
  573.     offset_rect ( &r, - xoff, - yoff );
  574.  
  575.     left   = r.left;
  576.     right  = r.right;
  577.     top    = r.top;
  578.     bottom = r.bottom;
  579.  
  580. /* ellipse is calculated by by the formula (x*x)/(a*a) + (y*y)/(b*b) = 1 */
  581. /* so I plug the point above the current into the formula and the point */
  582. /* to the right of the current into the formula and the one closest to 1 */
  583. /* is the next point on the ellipse */
  584.  
  585.     set_d(&r);   /* set A squared and B squares */
  586.  
  587.     x = left;
  588.     oldy = y = 0;
  589.  
  590.     CURx = x + xoff;
  591.     CURy = yoff;
  592.  
  593. /* draw the fisrt line or first 2 point of the ellipse */
  594.  
  595.     if ( OVALF )
  596.         hline ( CURx, ( xoff * 2 ) - CURx, CURy );
  597.     else
  598.     {
  599.     int disx, disy;
  600.  
  601.         disx = 2 * ( xoff - CURx );
  602.         disy = 2 * ( yoff - CURy );
  603.         do_pix();
  604.  
  605.         CURx += disx;
  606.         do_pix();
  607.     }
  608.  
  609.     while ( x < 0 )
  610.     {
  611.         d1 = do_d (x + 1, y );  /* plug next possible point into formula */
  612.         d2 = do_d (x, y + 1 );
  613.  
  614.         if ( d1 < d2 )        /* whic one is closest */
  615.         x++;
  616.         else
  617.         y++;
  618.  
  619.         CURx = x + xoff;        /* set next point relative ot screen */
  620.         CURy = yoff + y;
  621.  
  622.         if ( OVALF )
  623.         {
  624.         /* draw the line */
  625.         if ( oldy == y ) continue;
  626.         hline ( CURx, ( xoff * 2 ) - CURx, CURy );
  627.         CURx = x + xoff;
  628.         CURy -= ( abs ( CURy - yoff ) * 2 );
  629.         /* mirror the line around the x-axis */
  630.         hline ( CURx, ( xoff * 2 ) - CURx, CURy );
  631.         oldy = y;
  632.         }
  633.         else
  634.         {
  635.         int disx, disy;
  636.  
  637.         disx = 2 * ( xoff - CURx );
  638.         disy = 2 * ( yoff - CURy );
  639.  
  640.         /* plot a point in each qradrant */
  641.  
  642.         do_pix();
  643.  
  644.         CURx += disx;
  645.         do_pix();
  646.  
  647.         CURy += disy;
  648.         do_pix();
  649.  
  650.         CURx -= disx;
  651.         do_pix();
  652.         }
  653.     }
  654.     }
  655. }
  656.  
  657. /***********************************/
  658. /* hiline prints a horizontal line */
  659. /***********************************/
  660.  
  661. hline( x1, x2, y )
  662. int x1, x2, y;
  663. {
  664.     CURy = y;
  665.     for ( CURx = x1; CURx <= x2; CURx++ )
  666.     do_pix();
  667. }
  668.  
  669. static double a, b;
  670. /******************************************************************/
  671. /* set_d - computes A squared and B squared for the given ellipse */
  672. /******************************************************************/
  673.  
  674. static set_d ( r )
  675. rect_t *r;
  676. {
  677. double tmp;
  678.  
  679.     tmp = (double) ( ( - r->left ) + r->right ) / 2.0;
  680.     a = tmp * tmp;
  681.     tmp = (double) ( ( - r->top ) + r->bottom ) / 2.0;
  682.     b = tmp * tmp;
  683. }
  684. /******************************************************************************/
  685. /* do_d - plugs the given point into the ellipse form and returns the answer  */
  686. /******************************************************************************/
  687.  
  688. static double do_d( x, y )
  689. int x, y;
  690. {
  691.     return ( abs ( ( (double) ( x * x ) / a ) + ( (double) ( y * y ) / b ) ) );
  692. }
  693.  
  694. static int fence;
  695.  
  696. /*+1***************************************************************************/
  697. /*                                          */
  698. /*    fill_poly   -    fills the polygon                      */
  699. /*                                          */
  700. /*    description -    fills the given polygon by building a move table of   */
  701. /*            the polygon, then feeds it into the fill algorithm.   */
  702. /*            The fill algorithm works by xoring a line from the    */
  703. /*            bounding box to current point on the polygon.  All    */
  704. /*            points on the inside are xored an odd number of times */
  705. /*            so they stay the color while point on the outside are */
  706. /*            xored en eved number of times so they return to the   */
  707. /*            original color.                       */
  708. /*                                          */
  709. /*    parameters  -    fill_poly(poly);                      */
  710. /*            poly_t *poly;    polygon to be filled              */
  711. /*                                          */
  712. /*    returns     -    nothing                           */
  713. /*                                          */
  714. /*    Programmer  -    Jeff Wrench                          */
  715. /*                                          */
  716. /*-1***************************************************************************/
  717.  
  718. fill_poly(poly_pointer)
  719. poly_t *poly_pointer;
  720. {
  721. char table[4000], *p = table, move;
  722. int x, y, n, i;
  723.  
  724.     build_tab(poly_pointer, table);
  725.  
  726.     x = poly_pointer->point->point.x;    /* get starting point */
  727.     y = poly_pointer->point->point.y;
  728.  
  729.     n = 1;
  730.  
  731.     p = table;
  732.  
  733.     for ( move = get_move( &n, &p ); move;  /* move until finished with poly */
  734.       move = get_move( &n, &p ) )
  735.     {
  736.     switch ( move )
  737.     {
  738.         case RT:        /* move right */
  739.             x++;
  740.             break;
  741.         case LT:        /* move left */
  742.             x--;
  743.             break;
  744.         case UP:        /* move up */
  745.             clr_line( x, y++ );
  746.             break;
  747.         case DN:        /* move down */
  748.             clr_line( x, --y );
  749.             break;
  750.         case UPRT:        /* move up right */
  751.             clr_line( ++x, y++ );
  752.             break;
  753.         case UPLT:        /* move up left */
  754.             clr_line( --x, y++ );
  755.             break;
  756.         case DNRT:        /* move down right */
  757.             clr_line( ++x, --y );
  758.             break;
  759.         case DNLT:        /* move down left */
  760.             clr_line( --x, --y );
  761.             break;
  762.  
  763.  
  764.     }
  765.     }
  766. }
  767.  
  768. /**************************************************/
  769. /* clr_line - xor's a line with the current color */
  770. /**************************************************/
  771.  
  772. clr_line( x, y )
  773. {
  774. int i;
  775.  
  776.     for ( i = fence; i < x; i++ )
  777.     xor_pix ( i, y );
  778. }
  779.  
  780. /*+1***************************************************************************/
  781. /*                                          */
  782. /*    build_tab   -    Builds a move table                      */
  783. /*                                          */
  784. /*    description -    Builds a move table                      */
  785. /*                                          */
  786. /*    parameters  -    build_table( poly, table );                  */
  787. /*            poly_t *poly;        poly to build              */
  788. /*            char   *table;        table to put moves          */
  789. /*                                          */
  790. /*    returns     -    nothing                           */
  791. /*                                          */
  792. /*    programmer  -    Jeff Wrench                          */
  793. /*                                          */
  794. /*-1***************************************************************************/
  795.  
  796. build_tab ( poly, table )
  797. poly_t *poly;
  798. char *table;
  799. {
  800. int x1, x2, y1, y2, n = 1;
  801. int ox1 = -1, ox2 = -1, oy1 = -1, oy2 = -1;
  802. int cd1, cd2, point_in;
  803. char *p;
  804. cpoint_t *np, *sp, *bp, *ep, *lp;
  805.  
  806.     p = table;
  807.  
  808.     /* are there two point on the polygon */
  809.     if ( ( ! poly ) || ( ! poly->point ) || ( ! poly->point->next ) ) /* no */
  810.     {
  811.     table[0] = 0;
  812.     return;
  813.     }
  814.  
  815.     x2 = poly->point->point.x;    /* get first point */
  816.     y2 = poly->point->point.y;
  817.  
  818.     fence = x2;
  819.  
  820.     for ( np = poly->point->next; np; np = np->next )
  821.     {
  822.  
  823.     x1 = x2;    /* reset first point to old last point */
  824.     y1 = y2;
  825.  
  826.     x2 = np->point.x;  /* get the new last point */
  827.     y2 = np->point.y;
  828.  
  829.     do_line(x1, y1, x2, y2, &p, &n);  /* do the line */
  830.     }
  831.     *(++p) = '\0';      /* end table with a null */
  832. }
  833.  
  834. /*+1***************************************************************************/
  835. /*                                          */
  836. /*    do_line     -    builds a line of moves                      */
  837. /*                                          */
  838. /*    description -    builds a line of moves and puts them in the table     */
  839. /*            the algorithm is the same as line()              */
  840. /*                                          */
  841. /*    parameters  -    do_line ( x1, y1, x2, x2, p, n )              */
  842. /*            int x1, y1;    starting point                  */
  843. /*            int x2, y2;    ending point                  */
  844. /*            char **p;    pointer to pointer into the table     */
  845. /*                                          */
  846. /*    returns     -    nothing                           */
  847. /*                                          */
  848. /*    Programmer  -    Jeff Wrench                          */
  849. /*                                          */
  850. /*-1***************************************************************************/
  851.  
  852. do_line(x1, y1, x2, y2, p, n)
  853. int x1, y1, x2, y2, *n;
  854. char **p;
  855. {
  856. int xprev, yprev, byts;
  857. int dx, dy, adx, ady, xa, ya, d, incr1, incr2;
  858.  
  859.     if ( fence > x2 ) fence = x2;
  860.  
  861.     xprev = x1;
  862.     yprev = y1;
  863.  
  864.     dx = x2-x1;
  865.     dy = y2-y1;
  866.  
  867.     if ( dx < 0 )       /* Set up to move backwards on the X-axis */
  868.     {
  869.     xa = -1;
  870.     adx = -dx;
  871.     }
  872.     else          /* Set up to move forwards on the X-axis */
  873.     {
  874.     xa =  1;
  875.     adx = dx;
  876.     }
  877.  
  878.     if ( dy < 0 )       /* Set up to move backwards on the Y-axis */
  879.     {
  880.     ya = -1;
  881.     ady = -dy;
  882.     }
  883.     else          /* Set up to move forwards on the Y-axis */
  884.     {
  885.     ya =  1;
  886.     ady = dy;
  887.     }
  888.  
  889.     if (adx > ady)
  890.     {
  891.     incr1 = ady << 1;
  892.     incr2 = (d = incr1 - adx) - adx;
  893.  
  894.     do
  895.     {
  896.         x1 += xa;
  897.         if (d < 0)
  898.         d += incr1;
  899.         else
  900.         {
  901.         y1 += ya;
  902.         d += incr2;
  903.         }
  904.         **p = do_move(x1-xprev,y1-yprev,**p,n);
  905.         xprev = x1;
  906.         yprev = y1;
  907.         if ( *n )
  908.         {
  909.         *(++(*p)) = '\0';
  910.         ++byts;
  911.         }
  912.     } while (x1 != x2);
  913.     }
  914.     else
  915.     {
  916.        incr1 = adx << 1;
  917.        incr2 = (d = incr1 - ady) - ady;
  918.  
  919.     do
  920.     {
  921.         y1 += ya;
  922.         if (d < 0)
  923.         d += incr1;
  924.         else
  925.         {
  926.         x1 += xa;
  927.         d += incr2;
  928.         }
  929.         **p = do_move(x1-xprev,y1-yprev,**p,n);
  930.         xprev = x1;
  931.         yprev = y1;
  932.         if ( *n )
  933.         {
  934.         *(++(*p)) = '\0';
  935.         ++byts;
  936.         }
  937.     } while (y1 != y2);
  938.     }
  939. }
  940.  
  941. /*+1***************************************************************************/
  942. /*                                          */
  943. /*    do_move     -    does one pixel move                      */
  944. /*                                          */
  945. /*    description -    does a one pixel move                      */
  946. /*                                          */
  947. /*    parameters  -    do_move ( dx, dy, curbyt, n )                  */
  948. /*            int dx, dy;    direction of move              */
  949. /*            int curbyt;    the cyrrent byte of the table          */
  950. /*            int *n;     which nibble to put move in          */
  951. /*                                          */
  952. /*    returns     -    The new byte for the table                  */
  953. /*                                          */
  954. /*    programmer  -    Jeff Wrench                          */
  955. /*                                          */
  956. /*-1***************************************************************************/
  957.  
  958. do_move(dx,dy,curbyt,n)
  959. int dx, dy, *n, curbyt;
  960. {
  961.  
  962. unsigned int nibble;
  963.  
  964.     nibble = 0;
  965.  
  966.     if (dx)
  967.     {
  968.     if (dx < 0)
  969.         nibble = 0x0c;
  970.     else
  971.         nibble = 0x04;
  972.      }
  973.  
  974.     if (dy)
  975.     {
  976.     if (dy < 0)
  977.         nibble |= 0x03;
  978.     else
  979.         nibble |= 0x01;
  980.      }
  981.  
  982.  
  983.     /* put the move into the proper nibble */
  984.     nibble = (*n) ? (nibble << 4) : (curbyt  & 0xfff0 ) | nibble;
  985.  
  986.     if (*n)
  987.     *n = 0;
  988.     else
  989.     *n = 1;
  990.  
  991.     return (nibble);
  992. }
  993.  
  994. /*+1***************************************************************************/
  995. /*                                          */
  996. /*    get_move    -    gets the next move                      */
  997. /*                                          */
  998. /*    description -    gets the next move from the move table              */
  999. /*                                          */
  1000. /*    parameters  -    get_move ( n, p )                      */
  1001. /*            int *n;    which nibble to use                  */
  1002. /*            char **p;  pointer to a pointer into the table          */
  1003. /*                                          */
  1004. /*    returns     -    the new move                          */
  1005. /*                                          */
  1006. /*    programmer  -    Jeff Wrench                          */
  1007. /*                                          */
  1008. /*-1***************************************************************************/
  1009.  
  1010. char get_move( n, p )
  1011. int *n;
  1012. char **p;
  1013. {
  1014. char *p1, nibble;
  1015.  
  1016.     p1 = *p;
  1017.  
  1018.     nibble = *p1;
  1019.  
  1020.     if ( *n )        /* get right nibble */
  1021.     {
  1022.     nibble = ( nibble >> 4 ) & 0x0f;
  1023.     *n = 0;
  1024.     }
  1025.     else
  1026.     {
  1027.     nibble &= 0x0f;
  1028.     *n = 1;
  1029.     (*p)++;     /* if last nibble inc to byte of table */
  1030.     }
  1031.  
  1032.  
  1033.     return (nibble);
  1034. }
  1035.  
  1036. /*+1***************************************************************************/
  1037. /*                                          */
  1038. /*    do_pix        -    Does a pixel                          */
  1039. /*                                          */
  1040. /*    description -    Turns the given pixel to the current set_color          */
  1041. /*                                          */
  1042. /*    parmeters  -   do_pix ()                          */
  1043. /*                                          */
  1044. /*    returns     -    Nothing                           */
  1045. /*                                          */
  1046. /*    Programmer  -    Jeff Wrench                          */
  1047. /*                                          */
  1048. /*-1***************************************************************************/
  1049.  
  1050. do_pix()
  1051. {
  1052.     if (  CURx & 1 )
  1053.     colorb = ( color >> 2 ) & 3;
  1054.     else
  1055.     colorb = color & 3;
  1056.  
  1057.     reg1.ax = 0xc00 | colorb;
  1058.     reg1.cx = CURx;
  1059.     reg1.dx = CURy;
  1060.     sysint( 0x10, ®1, ®2 );
  1061. }
  1062.  
  1063. /*+1***************************************************************************/
  1064. /*                                          */
  1065. /*    xor_pix     -    Does a pixel                          */
  1066. /*                                          */
  1067. /*    description -    Turns the given pixel to the current set_color          */
  1068. /*            after clipping the pixel                  */
  1069. /*                                          */
  1070. /*    parameters  -    xor_pix( x, y )                       */
  1071. /*                                          */
  1072. /*    returns     -    Nothing                           */
  1073. /*                                          */
  1074. /*    Programmer  -    Jeff Wrench                          */
  1075. /*                                          */
  1076. /*-1***************************************************************************/
  1077.  
  1078. xor_pix( x, y )
  1079. int x, y;
  1080. {
  1081.     if ( clip_code ( x, y, cur_win ) )    /* is pixel in window */
  1082.     return;     /* no */
  1083.  
  1084.     map ( &x, &y );    /* map to screen */
  1085.  
  1086.     if (  x & 1 )
  1087.     colorb = ( color >> 2 ) & 3;
  1088.     else
  1089.     colorb = color & 3;
  1090.  
  1091.     reg1.ax = 0xc80 | colorb;
  1092.     reg1.cx = x;
  1093.     reg1.dx = y;
  1094.     sysint( 0x10, ®1, ®2 );
  1095. }
  1096.  
  1097. /*+1***************************************************************************/
  1098. /*                                          */
  1099. /*    genchr        -    getnerates a character                      */
  1100. /*                                          */
  1101. /*    description -    generates a character at the given position, I use    */
  1102. /*            instead of BIOS because I want to start a character   */
  1103. /*            anywhere on screen/                      */
  1104. /*                                          */
  1105. /*    parameters  -    genchr( x, y, chr )                      */
  1106. /*            int x, y;    position of upper left of character   */
  1107. /*            char chr;    character to print              */
  1108. /*                                          */
  1109. /*    returns     -    nothing                           */
  1110. /*                                          */
  1111. /*    Programmer  -    Jeff Wrench                          */
  1112. /*                                          */
  1113. /*-1***************************************************************************/
  1114.  
  1115. genchr ( x, y, chr )
  1116. int x, y;
  1117. char chr;
  1118. {
  1119. unsigned pos, seg;
  1120. int i, j;
  1121. int chrtodo[8];
  1122. int savx, savy;
  1123.  
  1124.     savx = CURx;
  1125.     savy = CURy;
  1126.  
  1127.     if ( chr < 128 )
  1128.     {
  1129.     pos = (int) chr << 3;    /* mult by 8 because 8 bytes per char */
  1130.     pos += 0xfa6e;        /* BIOS character table for first 128 chars */
  1131.     seg = 0xf000;
  1132.     }
  1133.     else
  1134.     {
  1135.     pos = ( (int) chr - 128 ) << 3; /* mult by 8 because 8 bytes per char */
  1136.     pos += peek ( 0x1f * 4, 0 );
  1137.     seg = peek ( ( 0x1f * 4 ) + 2, 0 );
  1138.     }
  1139.  
  1140.     for ( i = 0; i < 8; i++ )        /* read the char into memory */
  1141.     chrtodo[i] = peek ( pos + i, seg ) & 0xff;
  1142.  
  1143.     for ( i = 0; i < 8; i++ )        /* eight lines per char of */
  1144.     for ( j = 0; j < 8; j++ )    /*eight bits across */
  1145.     {
  1146.         chrtodo[i] <<= 1;
  1147.         if ( chrtodo[i] & 0x100 )        /* is this bit on */
  1148.         {                    /* if so turn the pixel on */
  1149.         CURx = x + j;
  1150.         CURy = y + i;
  1151.         do_pix();
  1152.         }
  1153.     }
  1154.  
  1155.     CURx = savx;
  1156.     CURy = savy;
  1157. }
  1158.  
  1159. /**********************************************/
  1160. /* move_to - moves current position to (x, y) */
  1161. /**********************************************/
  1162.  
  1163. move_to(x, y)
  1164. int    x, y;
  1165. {
  1166.     CURx = x;
  1167.     CURy = y;
  1168. }
  1169.  
  1170. /***************************************************************/
  1171. /* move - moves current position to (x + current, y + current) */
  1172. /***************************************************************/
  1173.  
  1174. move(x, y)
  1175. int    x, y;
  1176. {
  1177.     CURx += x;
  1178.     CURy += y;
  1179. }
  1180.  
  1181.  
  1182. #ifdef MICROSOFT
  1183.  
  1184. /*
  1185.  *    provide an equivalent peek function for Microsoft
  1186.  */
  1187.  
  1188. int peek(offset, segment)
  1189. int offset, segment;
  1190. {
  1191.  
  1192.     int far *ip;
  1193.  
  1194.     ip = (int far *)((long)segment * 65536l + (long)offset);
  1195.     return(*ip);
  1196.  
  1197. }
  1198.  
  1199. #endif
  1200.